#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import time
import random
import commands
import re
import base64
import string
from recvDataFromSensor import *
DEBUG = 3 #1:not using serial ,2:not using serial but in its logic 3:using serial

def get_IP():
    ip_content = commands.getoutput('ifconfig')
    return re.findall('wlan0.*\n.* inet addr:([^ ]+) ',ip_content)[0]
def ctrl_end():
    try:
        pass
    except KeybordInterrupt:
        print 'ctrl+d or z,end'
        return True
    return False

def verify(ver_res,data):
    #cnum = 32
    try:
        s2 = base64.decodestring(ver_res)
        #print 'de:s2:'+s2
    except :
        #print 'decode error1'
        return False
    try:
        #print 's2[4:-5]:'+s2[4:-4]
        s1 = base64.decodestring(s2[4:-4])
        #print 'de:s1'+s1
    except :
        #print 'decode error2'
        return False
    print 'v:s1 ',s1
    if s1 == data:
        print 'True'
        return True
    else:
        print 'False'
        return False

def show_except_socket(e):
    print 'Error close socket:%s' % e
    
def close_socket(sockobj) :
    try:
        sockobj.close()  
    except socket.error, e :    
        show_except_socket(e)
        sys.exit(-1)

def receive_msg(sockobj):
    buf = ''
    while True:
        try:
            buf = sockobj.recv(1024)
        except socket.error,e:
            show_except_socket(e)
            close_socket(sockobj)
            return False
        if not len(buf) or buf == '' or buf == None:
            # print 'Socket closed'
            # close_socket(sockobj)
            # break
            continue
        else:
            break
        
    if not len(buf):return ''
    else:return buf

# def verify_str(ver_data):
#
#     print ver_data
#
#     s1 = base64.encodestring(ver_data)
#     print 'en:s1:',s1
#     salt = ''
#     for i in range(0,4):
#         salt += chr(random.randint(0,25)+ord('A'))
#     s2 = salt+s1+salt #salt is random str
#     s2 = base64.encodestring(str(s2))
#
#     print 'en:s2:',s2
#     return s2
'''
the process: send test info -->receive info about the verification --> send the ACK --> receive the command --> send the ACK
--> send the sensor data
'''
def client_commu(conn,addr):
    #send test info
    data = ''
    for i in range(0,16):
        data += chr(random.randint(0,25)+ord('A'))
    try:
        conn.send(data)
    except socket.error,e:
        show_except_socket(e)
        close_socket(conn)
        return
    #print 'the verify result should be:'+verify_str(data)
    #receive info about the verification
    flag = False
    for i in range(0,10):
        buf =  receive_msg(conn)

        if buf == False:
            print 'Connection Error'
            return
        if buf == '':
            print 'fail to receiving the msg'
            continue
        print 'receiving:' + buf
        flag = verify(buf,data)#the verification


        if flag == True:
            print 'legal client'
            flag = True
            break
        else:
            flag = False
            break
    if flag == False:print 'illegal client';close_socket(conn);return;

    #send ACK to legal client
    data = 'ACK'
    try:
        conn.send(data)
    except socket.error,e:
        show_except_socket(e)
        close_socket(conn)
        return 

    #get the command
    command = receive_msg(conn)
    print 'receiving command:',command,' from:',addr
    try:#TODO:change the sending data here
        print 'sending ACK'
        conn.send('ACK')
    except socket.error,e:
        show_except_socket(e)
        close_socket(conn)
        return

    time.sleep(0.5)#avoid the situation:sending interval too short : 'ACK5.8'

    argu = command.split("&")#init
    switch = int((argu[0].split('='))[1])
    points = int((argu[1].split('='))[1])
    frequence = int((argu[2].split('='))[1])
    print 'para:',switch,points,frequence

    if switch == 0:#TODO:close the sensor
        pass
    else:#send the data
		ser = None
		if DEBUG == 3:
			print 'init serial...'
			ser = init_serial()
		
		for i in range(0,points):
			data = None
			if DEBUG == 1:
				data =  ("%.1f" % random.uniform(3,10))#TODO:change the sending data here,get it from the sensor
			else:
				if ser != None:#DEBUG 3
					#data = ("%.lf" % (recv_once(ser))
					data = recv_once(ser)
					print 'test data:',data
					data = data[3:] 
					#res_data = string.atof(data)

					#print res_data
					if data != None:
						try:
							conn.send(data)
							print 'send:',data
						except socket.error,e:
							show_except_socket(e)
							close_socket(conn)
							return
					else:
						print 'fail to recv the data'
				else:#DEBUG 2
					#TODO:delete later,just for test
					data =  ("%.1f" % random.uniform(3,10))
					if data != None:
						try:
							conn.send(data)
							print 'send:',data
						except socket.error,e:
							show_except_socket(e)
							close_socket(conn)
							return
					else:
						print 'fail to recv the data'
					
				
			time.sleep(frequence)
		
		if DEBUG == 3:
			if ser != None:
				recv_close(ser)
				print 'close the serial'
    conn.close()

if __name__ == '__main__':
    #myHost = '192.168.155.1'

    #myHost = socket.gethostbyname(socket.getfqdn(socket.gethostname()))
    myHost = get_IP()
    myPort = 50002

    sockobj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    sockobj.bind((myHost,myPort))
    sockobj.listen(10)
    print "start server:IP:",myHost,":",myPort
    #cnt = 0
    while True:
        print 'I am listenning'
        try:
            conn, addr = sockobj.accept()
        except socket.error,e:
            print 'timed out'
            #show_except_socket(e)
            #close_socket(conn)
            continue
        print "Connected By:" ,addr
        #start_new_thread(client_thread,(conn,addr))
        client_commu(conn,addr)
        if ctrl_end() == True:
            break
       
    #conn.close()
    socketobj.close()
